<?php

namespace app\api\controller\order;


use addons\epay\library\Service;
use app\admin\model\trades\assets\Order;
use app\common\controller\Api;
use app\common\library\Iden;
use Exception;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;
use think\Response;
use think\Session;
use app\admin\model\vactivities\Ticket;
use Endroid\QrCode\QrCode;
use Yansongda\Pay\Pay;
use think\Log;

// 允许跨域
header('Access-Control-Allow-Origin:*');//允许跨域

/**
 * 个人中心
 * 登录用户的个人主页
 * 参与人下订单
 */
class Confirm extends Api
{

    //如果$noNeedLogin为空表示所有接口都需要登录才能请求
    //如果$noNeedRight为空表示所有接口都需要验证权限才能请求
    //如果接口已经设置无需登录,那也就无需鉴权了
    //
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['*'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];

    protected $model = null;
    protected $catemodel = null;
    protected $tagsmodel = null;
    protected $actmodel = null;
    protected $ticket_model = null;
    protected $aact = null;
    protected $api_act = null;
    protected $mem_model = null;
    protected $Infomodel = null;
    protected $gainlogmodel = null;
    protected $gainmodel = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\trades\assets\Order;//订单
        $this->Infomodel = new \app\admin\model\trades\assets\Orderinfo;//订单详情
        $this->gainlogmodel = new \app\admin\model\trades\order\Gainlog;//收益详情
        $this->gainmodel = new \app\admin\model\trades\order\Gain;//收益总表
        $this->actmodel = new \app\admin\model\vactivities\Activity;
        $this->catemodel = new \app\admin\model\superdata\Activitycategory;
        $this->tagsmodel = new \app\admin\model\superdata\Activitytags;
        $this->ticket_model = new \app\admin\model\vactivities\Ticket;
        $this->admin_model = new \app\admin\model\Admin;
        $this->mem_model = new \app\admin\model\member\Account;

    }



    /*
     * 报名活动信息
     */
    public function info(){

        $uInfo = $this->auth->getUserInfo();
        if(empty($uInfo)){//未登录
            $this->error(__('Please login first'), null, 401);
        }
        $admin_id = Iden::decrypt($uInfo['id']);
        if(empty($admin_id)){
            $this->error(__('获取用户参数出错'));
        }
        $ids = $this->request->param("ids");//活动id
        //$isticket = $this->request->param("isticket");//参与人选项 0 注册加入活动-报名 1 入场劵加入活动-购买 2 直接加入活动
        if (!$ids) {
            $this->error(__('获取参数错误'),'',0);
        }
        $ids = Iden::decrypt($ids);
        $row = $this->actmodel->where(['id' => $ids])->Field('id,startTime,isticket,thumb,name,admin_id')->find();
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $r = [];
        $r['id'] = Iden::encrypt($row['id']);
        $r['startTime'] = date('Y-m-d H:i:s',$row['startTime']);
        $r['isticket'] = $row['isticket'];
        $r['name'] = $row['name'];
        if($row['thumb']){
            $thumbArr = explode(',',$row['thumb']);
            $r['thumb'] = !empty($thumbArr) ? $thumbArr:'';
        }
        if(isset($r) && $r['isticket'] == Ticket::IS_TICKET_1){//如果是购买则显示门票信
            $tlist = $this->ticket_model->getTicketList($row['id'],Ticket::TICKET_TYPE_2,$row['admin_id']);
            //print_r($tlist);

            if($tlist){
                foreach ($tlist as $k=>$v) {
                    $r['ticket'][]=$v;
                }
            }
        }
        $this->success(__('读取成功'), $r, 200);
    }


    /*
     * 参与活动选项
     */
    public function order(){

        $uInfo = $this->auth->getUserInfo();
        if(empty($uInfo)){//未登录
            $this->error(__('Please login first'), null, 401);
        }
        $admin_id = Iden::decrypt($uInfo['id']);
        if(empty($admin_id)){
            $this->error(__('获取用户参数出错'));
        }

        $ids = $this->request->param("ids");//活动id

        if (!$ids) {
            $this->error(__('获取参数错误'),'',0);
        }
        $ids =  Iden::decrypt($ids);
        $row = $this->actmodel->get(['id' => $ids]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $row = $row->toArray();
        //print_r($row);
        if($row['status']!= $this->actmodel::ACTIVITY_STATUS_1){
            $this->error('活动状态有误');
        }
        $isticket = $row['isticket'];


        $tArr = [$this->actmodel::TICKET_STATUS_0,$this->actmodel::TICKET_STATUS_1,$this->actmodel::TICKET_STATUS_2];
        if(!in_array($isticket,$tArr)){
            $this->error(__('获取票务类型错误'),'',0);
        }

        switch ($isticket)
        {
            case 0://报名
                return $this->_enroll($ids);
                break;
            case 1://购买
                return $this->_buy($ids);
            case 2://直接加入活动
                return $this->_join($ids);
                break;
            default:
                return false;
                break;
        }

    }


    /*
     * $ids 活动 id
     * 报名
     */

    private function _enroll($ids){

        $uInfo = $this->auth->getUserInfo();
        if(empty($uInfo)){//未登录
            $this->error(__('Please login first'), null, 401);
        }
        $admin_id = Iden::decrypt($uInfo['id']);
        if(empty($admin_id)){
            $this->error(__('获取用户参数出错'));
        }
      //  $admin_id = 1;

        if(empty($ids)){
            $this->error(__('获取参数错误'), null, 0);
        }
        $row = $this->actmodel->get(['id' => $ids]);

        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $row = $row->toArray();
        $account_id = $row['admin_id'];
        $series_id = isset($row['series_id']) && $row['series_id'] > 0 ? 1:2;//1系列 2 活动
        $name = $row['name'];
        $r = $this->model->getUserIsEnroll($row['id'],$admin_id);
        if($r){
            $this->error('此活动您已报过名了，不能重复报了', null, 0);
        }
        try{
            $params = [
                'orderid'=>trade_no(),
                'account_id'=>$account_id,//举办人
                'buyer_id'=>$admin_id,
                'activity_id'=>$ids,
                'amount'=>0,
                'paytype'=>0,
                'paytime'=>0,
                'state'=>$this->model::PAY_STATE_2,
                'createTime'=>time(),
                'ordertype'=>$series_id,
                'name'=>$name,
                'ticket_type'=>$row['isticket'],
                'sn'=>0
            ];
         //   print_r($params);die;
            $response =  $this->model->save($params);
            if(!$response){
                $this->error('生成订单失败');
            }
           //return $response;
        }catch (ValidateException $e) {
            $this->error($e->getMessage());
            log::error($e->getMessage());
        } catch (PDOException $e) {
            $this->error($e->getMessage());
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
        $data['name'] = $name;
        $data['username'] = $this->mem_model::getUsrNameById($account_id);
        $data['startTime'] = date('Y-m-d H:i:s',$row['startTime']);
        $this->success(__('报名成功'), $data, 200);
    }


    /*
     * 获取购买的数据并且生订单
     */
    private function _buy($ids){

        $uInfo = $this->auth->getUserInfo();
        if(empty($uInfo)){//未登录
            $this->error(__('Please login first'), null, 401);
        }
        $admin_id = Iden::decrypt($uInfo['id']);

        if(empty($admin_id)){
            $this->error(__('获取用户参数出错'));
        }

        if(empty($ids)){
            $this->error(__('获取参数错误'), null, 0);
        }
        $row = $this->actmodel->get(['id' => $ids]);

        if (!$row) {
            $this->error(__('No Results were found'));
         }

        $row = $row->toArray();

        $account_id = $row['admin_id'];
        $series_id = isset($row['series_id']) && $row['series_id'] > 0 ? 1:2;//1系列 2 活动
        $name = $row['name'];

        $tlist = [];

       // echo $account_id;
        //echo '---';
        //print_r($row);die;
        if(isset($row) && $row['isticket'] == Ticket::IS_TICKET_1){//如果是购买则显示门票数
            $tlist = $this->ticket_model->getTicketList($ids,Ticket::TICKET_TYPE_2,$account_id);
        }

        if(empty($tlist)){
            $this->error('没有找到门票','',0);
        }

        $json = $this->request->param("data/a");
        $data = $json;
        if(empty($data)){
            $this->error('没有获取到您提交的数据','',0);
        }
        $count = count(array_filter($data));
        if($count == 0){
            $this->error('您提交的数组数据不能为空','',0);
        }

        $data = array_filter($data);

//        $data =[
//            'total'=>30,
//
//            'info'=>[
//
//                ['tid' =>30,'price'=>40,'number'=>3],
//                ['tid' =>31,'price'=>3,'number'=>1],
//                ['tid' =>32,'price'=>10,'number'=>2],
//            ]
//            ];

        if(!empty($data) && !empty($tlist)){//两组数据作对比
            $this->arr_comp($data,$tlist);
        }

        $result = false;
        Db::startTrans();
        try {

            $param = [
                'orderid'=>trade_no(),
                'account_id'=>$account_id,//举办人
                'buyer_id'=>$admin_id,
                'activity_id'=>$ids,
                'amount'=>priceyuantofen($data['total']),
                'paytype'=>$this->model::PAY_TYPE_2,
                'paytime'=>0,
                'state'=>$this->model::PAY_STATE_1,
                'createTime'=>time(),
                'utime'=>0,
                'ordertype'=>$series_id,
                'name'=>$name,
                'ticket_type'=>$row['isticket'],
                'sn'=>0
            ];
            $r =  $this->model->save($param);//订单表
            if($r && isset($data['info'])){
                foreach($data['info'] as $k=>$v){
                    $t[] = [
                        'oid'=>$this->model->id,
                        'buy_id'=>$admin_id,
                        'ctime'=>time(),
                        'tid'=>$v['tid'],
                        'number'=>$v['number'],
                        'price'=>priceyuantofen($v['price'])
                    ];
                }

                $count = count(array_filter($t));
                if($count > 0 ){
                    $this->Infomodel->insetAll($t);//订单详情表
                }
            }

            if($r){
                $g = [
                    'account_id'=>$account_id,//举办人
                    'buyer_id'=>$admin_id,
                    'ctime'=>time(),
                    'orderid'=>$this->model->id,
                    'state'=>$this->model::PAY_STATE_1,
                    'amount'=>priceyuantofen($data['total']),
                    'activity_id'=>$ids,
                    'activity_type'=>$series_id
                ];

                $result = $this->gainlogmodel->save($g);//收益详情表

                $r = $this->gainmodel->getGainInfo($account_id);//查找收益总表有无数据
                if(empty($r)){
                    $gl = [
                        'account_id'=>$account_id,//举办人
                        'total'=>priceyuantofen($data['total']),
                        'balance'=>0,
                        'temp'=>0,
                        'ctime'=>time()
                    ];
                    $this->gainmodel->save($gl);//收益表
                }
            }

           Db::commit();
         }catch (ValidateException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (PDOException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result !== false) {
            $this->scan_order($this->model->id);//生成支付二维码图片
           // $this->test_order($this->model->id);//生成支付二维码图片
            $this->reduce_ticket($this->model->id);//减去门票数量
            $this->success('生成订单成功','',200);
        } else {
            $this->error(__('No rows were inserted'));
        }

    }

    /*
     * 减票的数量
     */
    public function reduce_ticket($oid){
        $res = Db::name("order_info")->where('oid', $oid)->select();
        $ts = [];
        if($res){
                foreach($res as $k=>$v){
                    $t = Db::name("activity_ticket")->where('id', $v['tid'])->find();
                    if(empty($t)){
                        $this->error('没有查到此票据');
                    }
                    if($v['number'] > $t['temp']){
                        $this->error('当前购买的票数量大于剩余票数量');
                    }
                    $ts[]=[
                        'id' =>$v['tid'],
                        'temp'=>$t['temp'] - $v['number'],
                    ];
                }

               // print_r($ts);die;

            if(!empty($ts)){//批量更新
                $this->ticket_model->updataAll($ts);
            }
          //  unset($ts);
            return true;
        }else{
            $this->error('没有查到此订单购买的票据信息');
        }

    }

    /*
     * 二个数组作对比
     * Array
(
[total] => 30
[info] => Array
(
[0] => Array
(
[tid] => 30
[price] => 40
[number] => 10
)

[1] => Array
(
[tid] => 31
[price] => 3
[number] => 60
)

[2] => Array
(
[tid] => 32
[price] => 10
[number] => 10
)

)

)
----Array
(
[0] => Array
(
[id] => 30
[name] => VIP入场券
[price] => 0.00
[number] => 50
[end_time] => 1970-01-01 08:00:00
[intro] =>
[temp] => 20
)

[1] => Array
(
[id] => 31
[name] => 入场券名称
[price] => 5.00
[number] => 33
[end_time] => 1970-01-01 08:00:00
[intro] =>
[temp] => 18
)

[2] => Array
(
[id] => 32
[name] => 入场券名称活动
[price] => 9.00
[number] => 99
[end_time] => 1970-01-01 08:00:00
[intro] =>
[temp] => 19
)

)
    $a代表购买提交的数据
    $b代表活动对应的票信息
    */
    public function arr_comp($a,$b){
        if(isset($a) && !empty($a) && isset($b) && !empty($b)){
            foreach ($a['info'] as $k=>$v){
                if(isset($b[$k]) && $b[$k]['id'] > 0){
                    if($v['tid'] == $b[$k]['id']){
                        if($v['number'] > $b[$k]['temp']){
                            $this->error($b[$k]['name'].'票量不足,请购买数量小于等于'.$b[$k]['temp'].'张','',0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 生成二维码
     * */
    public function qrcode()
    {
      //  $url = $this->request->param();
        $url = $this->request->get("payurl");
       // $url = $this->request->param();
       // $text = $this->request->get('text', $url['url']);
        if(empty($url)){
            $this->error('获取微信生成的二维网址出错','',0);
        }

        $text = $this->request->get('text', $url);
        $size = $this->request->get('size', 300);
        $padding = $this->request->get('padding', 15);
        $errorcorrection = $this->request->get('errorcorrection', 'medium');
        $foreground = $this->request->get('foreground', "#ffffff");
        $background = $this->request->get('background', "#000000");
        $logo = $this->request->get('logo');
        $logosize = $this->request->get('logosize');
        $label = $this->request->get('label');
        $labelfontsize = $this->request->get('labelfontsize');
        $labelhalign = $this->request->get('labelhalign');
        $labelvalign = $this->request->get('labelvalign');

        // 前景色
        list($r, $g, $b) = sscanf($foreground, "#%02x%02x%02x");
        $foregroundcolor = ['r' => $r, 'g' => $g, 'b' => $b];

        // 背景色
        list($r, $g, $b) = sscanf($background, "#%02x%02x%02x");
        $backgroundcolor = ['r' => $r, 'g' => $g, 'b' => $b];

        $qrCode = new QrCode();
        /*  $qrCode
              ->setSize($size)
              ->setText($text)
              ->setPadding($padding)
              ->setErrorCorrection($errorcorrection)
              ->setForegroundColor($foregroundcolor)
              ->setBackgroundColor($backgroundcolor)
              ->setLogoSize($logosize)
              ->setLabelFontPath(ROOT_PATH . 'public/assets/fonts/fzltxh.ttf')
              ->setLabel($label)
              ->setLabelFontSize($labelfontsize)
              ->setLabelHalign($labelhalign)
              ->setLabelValign($labelvalign)
              ->setImageType(QrCode::IMAGE_TYPE_PNG);*/


        $qrCode->setSize($size);
        $qrCode->setText($text);
        $qrCode->setPadding($padding);
        $qrCode->setErrorCorrection($errorcorrection);
        $qrCode->setForegroundColor($foregroundcolor);
        $qrCode->setBackgroundColor($backgroundcolor);
        $qrCode->setLogoSize($logosize);
        $qrCode->setLabelFontPath(ROOT_PATH . 'public/assets/fonts/fzltxh.ttf');
        $qrCode->setLabel($label);
        $qrCode->setLabelFontSize($labelfontsize);
        $qrCode->setLabelHalign($labelhalign);
        $qrCode->setLabelValign($labelvalign);
        $qrCode->setImageType(QrCode::IMAGE_TYPE_PNG);
        //也可以直接使用render方法输出结果
        //return $qrCode->render();
        return new Response($qrCode->get(), 200, ['Content-Type' => $qrCode->getContentType()]);
    }

    /**
     * 支付配置
     **/
    public static function getWechatConfig($type = 'wechat',$param = false)
    {
        $config = get_addon_config('epay');
        $config = isset($config[$type]) ? $config[$type] : $config['wechat'];
        if ($config['log']) {
            $config['log'] = [
                'file' => LOG_PATH . '/epaylogs/' . $type . '-' . date("Y-m-d") . '.log',
                'level' => 'debug'
            ];
        }

        if(isset($param) && $param['orderid'])
            $out_trade_no = $param['orderid'];
        else
            $out_trade_no = '';

       // $config['notify_url'] = request()->root(true) . '/addons/epay/payment/notifyx/paytype/';
        $config['notify_url'] = request()->root(true) .'/addons/epay/payment/notifyx/paytype/'.$type;
        //$config['notify_url'] = 'http://dev.onzoom.cn/addons/epay/payment/notifyx/paytype/'.$type;
        $config['notify_url'] = 'https://www.onzoom.cn/api/order/payment/notifyx/paytype/'.$type;
       // $config['returnurl'] = request()->root(true) . '/addons/epay/payment/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;
        $config['returnurl'] = 'https://www.onzoom.cn/api/order/payment/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;

        return $config;
    }

    /*
     * 生成二维码订单
     */
    public function scan_order($oid){

        $uInfo = $this->auth->getUserInfo();
        if(empty($uInfo)){//未登录
            $this->error(__('Please login first'), null, 401);
        }
        $admin_id = Iden::decrypt($uInfo['id']);
        if(empty($admin_id)){
            $this->error(__('获取用户参数出错'));
        }

        if(empty($oid)){
            $this->error(__('获取订单参数出错'));
        }

        $row = $this->model->get(['id' => $oid]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $row = $row->toArray();//订单信息

       $config = self::getWechatConfig('wechat',$row);

       $wechat = Pay::wechat($config);
       // $result = Pay::wechat($config)->web($data);

        $order = [
            'out_trade_no' => $row['orderid'],
            'body' => $row['name'] ,
            'total_fee' =>$row['amount'] *100,
               // 0.01*100,//$row['amount']
        ];
        $result = $wechat->scan($order);

        $orderObj = [];
        if(isset($result) && $result['return_code'] =='SUCCESS' && $result['return_msg'] == 'OK'){

            $orderObj['payurl'] = $result['code_url'];
           // $orderObj['payurl'] = $this->qrcode($result['code_url']);
            $this->success('生成二维码成功',$orderObj,200);
        }else{
            $this->error(__('生成二维码出错'), null, 0);
        }


    }
    /*
     * 支付成功获取订单id
     */
    public function pay_laster(){

        $uInfo = $this->auth->getUserInfo();
        if(empty($uInfo)){//未登录
            $this->error(__('Please login first'), null, 401);
        }

        $out_trade_no = $this->request->param('orderid');

        //但是不可以在此编写订单逻辑！！！
        $r =  Db::name("activity_order")->where('orderid',$out_trade_no)->find();

        if($r['state']!=2){
            $this->error('支付状态失败');
        }
        $this->success("支付成功", $r,200);

    }


    /*
     * 测试订单
     */
    public function test_order($oid){

        $uInfo = $this->auth->getUserInfo();
        if(empty($uInfo)){//未登录
            $this->error(__('Please login first'), null, 401);
        }
        $admin_id = Iden::decrypt($uInfo['id']);
        if(empty($admin_id)){
            $this->error(__('获取用户参数出错'));
        }

        if(empty($oid)){
            $this->error(__('获取订单参数出错'));
        }

        $row = $this->model->get(['id' => $oid]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $row = $row->toArray();//订单信息

        $amount =  $row['amount'];

      //  $amount = $this->request->request('amount');
        $type = $this->request->request('type','wechat');//支付类型  wechat aplipy 微信还是支付宝
        $method = $this->request->request('method','web');//支付方式  app  web

        if (!$amount || $amount < 0) {
            $this->error("支付金额必须大于0");
        }

        if (!$type || !in_array($type, ['alipay', 'wechat'])) {
            $this->error("支付类型不能为空");
        }

        //订单号
        $out_trade_no = $row['orderid'];

        //订单标题
        $title = $row['name'];

        //回调链接
        $notifyurl = $this->request->root(true) . '/addons/epay/index/notifyx/paytype/' . $type;
        $returnurl = $this->request->root(true) . '/addons/epay/index/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;

        $response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method);

        var_dump($response);
    }


    /*
     * 支付完成之后更新订单状态以及收益表
     */
    public function pay_last(){
        $orderid = '20210204145358945230';

        $sn = $this->request->param('sn','123456');
        $r =  Db::name("activity_order")->where('orderid',$orderid)->find();
        if(!$r){
            $this->error('没有此订单');
        }
        $amount = $r['amount'];
        $oid = $r['id'];
        $admin_id = $r['account_id'];
        $result = false;
        Db::startTrans();
        try {
            $param = [
                'paytime'=>time(),
                'state'=>$this->model::PAY_STATE_2,
                'sn'=>$sn
            ];
            Db::table('activity_order')->where('orderid', $orderid)->update($param);//订单表更新
            Db::table('activity_gain_log')->where('orderid', $oid)->update(['state'=>2]);// 收益详情表更新 $oid是自动生成的订单id
           $result =  Db::name('activity_gain')
                ->where('account_id',$admin_id)
                //->data($up)
                ->inc('temp',$amount)
                ->inc('total',$amount)
                ->update();//
            Db::commit();
        }catch (ValidateException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (PDOException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result !== false) {
              $this->success('订单更新成功','',200);
        } else {
            $this->error(__('No rows were inserted'));
        }
    }

}
